package org.termine.db;

import java.io.ByteArrayInputStream;
import java.io.ByteArrayOutputStream;
import java.io.IOException;
import java.io.ObjectInputStream;
import java.io.ObjectOutputStream;
import java.io.Serializable;

import javax.annotation.PostConstruct;
import javax.faces.bean.ApplicationScoped;
import javax.faces.bean.ManagedBean;

import org.termine.util.Base64Coder;

import redis.clients.jedis.Jedis;
import redis.clients.jedis.JedisPool;
import redis.clients.jedis.JedisPoolConfig;

@ManagedBean
@ApplicationScoped
public class RedisConnector implements Serializable {

	private static final long serialVersionUID = -4287563791448818388L;

	private static final String URL = "141.201.123.230";
	private static final String PASSWORD = "!1234567890";
	private static final int PORT = 6379;
	private static final int TIMEOUT = 10000;
	private static final int EXPIRE = 60; // minutes

	private JedisPool jedisPool;

	/*
	 * Init
	 */
	@PostConstruct
	public void init() {
		jedisPool = new JedisPool(new JedisPoolConfig(), URL, PORT, TIMEOUT, PASSWORD);
	}

	public Jedis getJedis() {
		return jedisPool.getResource();
	}

	public void returnJedis(Jedis jedis) {
		jedisPool.returnResource(jedis);
	}

	public void destroy() {
		jedisPool.destroy();
	}

	public void setExp(String key, String value) {
		Jedis jedis = getJedis();
		try {
			jedis.setex(key, EXPIRE * 60, value);
		} catch (Exception e) {
			e.printStackTrace();
		} finally {
			returnJedis(jedis);
		}
	}
	
	public Object get(String key) {
		Jedis jedis = getJedis();
		try {
			return RedisConnector.fromString(jedis.get(key));
		} catch (Exception e) {
			e.printStackTrace();
			return null;
		} finally {
			returnJedis(jedis);
		}
	}
	
	public void del(String key) {
		Jedis jedis = getJedis();
		try {
			jedis.del(key);
		} catch (Exception e) {
			e.printStackTrace();
		} finally {
			returnJedis(jedis);
		}
	}

	public static String toString(Serializable object) {
		ByteArrayOutputStream baos = new ByteArrayOutputStream();
		try {
			ObjectOutputStream oos = new ObjectOutputStream(baos);
			oos.writeObject(object);
			oos.close();
		} catch (IOException e) {
			e.printStackTrace();
		}
		return new String(Base64Coder.encode(baos.toByteArray()));
	}

	public static Object fromString(String string) throws Exception {
		byte[] data = Base64Coder.decode(string);
		ObjectInputStream ois = new ObjectInputStream(new ByteArrayInputStream(data));
		Object object = ois.readObject();
		ois.close();
		return object;
	}

}
